from tkinter import *
from tkinter import messagebox
from pymodbus.client import ModbusTcpClient


class ModbusWriter:
    def __init__(self, master):
        self.master = master
        master.title("Modbus寄存器写入工具")
        master.geometry("300x210")

        # 创建界面组件
        Label(master, text="从机IP地址:").grid(row=0, column=0, padx=5, pady=5)
        self.ip_entry = Entry(master, width=15)
        self.ip_entry.grid(row=0, column=1, padx=5, pady=5)
        self.ip_entry.insert(0, "192.168.1.199")  # 默认IP

        Label(master, text="端口:").grid(row=1, column=0, padx=5, pady=5)
        self.port_entry = Entry(master, width=8)
        self.port_entry.grid(row=1, column=1, padx=5, pady=5, sticky=W)
        self.port_entry.insert(0, "502")  # 默认端口

        Label(master, text="寄存器地址:").grid(row=2, column=0, padx=5, pady=5)
        self.addr_entry = Entry(master, width=8)
        self.addr_entry.grid(row=2, column=1, padx=5, pady=5, sticky=W)

        Label(master, text="写入值:").grid(row=3, column=0, padx=5, pady=5)
        self.value_entry = Entry(master, width=8)
        self.value_entry.grid(row=3, column=1, padx=5, pady=5, sticky=W)

        self.write_button = Button(master, text="写入寄存器", command=self.write_register)
        self.write_button.grid(row=4, column=0, columnspan=2, pady=10)

        self.status_label = Label(master, text="就绪", fg="blue")
        self.status_label.grid(row=5, column=0, columnspan=2)

    def validate_input(self):
        """验证输入有效性"""
        try:
            ip = self.ip_entry.get()
            port = int(self.port_entry.get())
            address = int(self.addr_entry.get())
            value = int(self.value_entry.get())
            return (ip, port, address, value)
        except ValueError:
            messagebox.showerror("输入错误", "请输入有效的数字")
            return None

    def write_register(self):
        """执行Modbus写入操作"""
        inputs = self.validate_input()
        if not inputs:
            return

        ip, port, address, value = inputs
        client = ModbusTcpClient(ip, port)

        try:
            # 尝试建立连接
            if not client.connect():
                raise ConnectionError("无法连接到从机设备")

            # 写入保持寄存器（功能码06）
            response = client.write_registers(address, value)

            if response.isError():
                self.status_label.config(text="写入失败", fg="red")
            else:
                self.status_label.config(text="写入成功", fg="green")

        except Exception as e:
            self.status_label.config(text=f"非法输入", fg="red")
            messagebox.showerror("通信错误", "非法输入")
        finally:
            client.close()


if __name__ == "__main__":
    root = Tk()
    app = ModbusWriter(root)
    root.mainloop()